package cc.rengu.igas.bsps.core.service.trans;

import cc.rengu.igas.bsps.common.constant.BspsAppParamConstant;
import cc.rengu.igas.bsps.common.dao.*;
import cc.rengu.igas.bsps.common.dao.impl.*;
import cc.rengu.igas.bsps.common.entity.*;
import cc.rengu.igas.bsps.common.enums.*;
import cc.rengu.igas.bsps.core.model.UserSessionInfo;
import cc.rengu.igas.bsps.core.service.base.ManageService;
import cc.rengu.igas.bsps.facade.base.Header;
import cc.rengu.igas.bsps.facade.bean.MchntBindInfoBean;
import cc.rengu.igas.bsps.facade.bean.PrivilegeInfoBean;
import cc.rengu.igas.bsps.facade.request.MobileBankMchntNoBindMchntRequest;
import cc.rengu.igas.bsps.facade.response.MobileBankMchntNoBindMchntResponse;
import cc.rengu.oltp.service.common.constant.AppConfigConstant;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.enums.OltpRpcdEnum;
import cc.rengu.oltp.service.common.enums.SmsTypeEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.realize.SmsService;
import cc.rengu.oltp.service.realize.impl.SmsServiceImpl;
import cc.rengu.oltp.utility.util.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.binary.Base64;

import java.util.ArrayList;
import java.util.List;

/**
 * @author zhangxuran
 * @version 1.0
 * @date 2020/04/13
 */
public class MobileBankMchntNoBindMchntService extends ManageService {

    @Override
    protected Object bizBeforeCust() throws Exception {
        MobileBankMchntNoBindMchntRequest mobileBankMchntNoBindMchntRequest = new MobileBankMchntNoBindMchntRequest();
        ConvertUtil.convertOutput(mobileBankMchntNoBindMchntRequest);
        return mobileBankMchntNoBindMchntRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        MobileBankMchntNoBindMchntRequest mobileBankMchntNoBindMchntRequest = (MobileBankMchntNoBindMchntRequest) request;
        /*获取请求信息参数：法人行，商户号，手机银行账户，设备唯一标识，绑定用户标识，验证码，验证码验证标识*/
        String instId = mobileBankMchntNoBindMchntRequest.getHeader().getInstId();
        String mchntNo = mobileBankMchntNoBindMchntRequest.getMchntNo();
        String userMobileId = mobileBankMchntNoBindMchntRequest.getUserMobileId();
        String devUniqueId = mobileBankMchntNoBindMchntRequest.getDevUniqueId();
        String bindUserId = mobileBankMchntNoBindMchntRequest.getBindUserId();
        String smsCode = mobileBankMchntNoBindMchntRequest.getSmsCode();
        String smsAuthId = mobileBankMchntNoBindMchntRequest.getSmsAuthId();
        String devModel = mobileBankMchntNoBindMchntRequest.getDevRiskInfo().getDevModel();
        Header header = mobileBankMchntNoBindMchntRequest.getHeader();
        String phoneBrandModel = mobileBankMchntNoBindMchntRequest.getPhoneBrandModel();
        String channelId = header.getChanlId();
        rglog.info("校验必填项字段");
        /*判断参数必填性*/
        if (StringUtil.isEmptyOrNull(mchntNo) || StringUtil.isEmptyOrNull(devUniqueId) || StringUtil.isEmptyOrNull(bindUserId)
                || StringUtil.isEmptyOrNull(smsCode) || StringUtil.isEmptyOrNull(smsAuthId)) {
            rglog.error("手机银行商户号绑定商户必填性校验失败!");
            throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
        }
        rglog.info("校验短信验证码");
        /*检验短信验证码*/
        SmsService smsService = new SmsServiceImpl();
        boolean smsFlag = smsService.verifySmsCode(instId, SmsTypeEnum.USER_REGISTER.getSmsType(), smsCode, smsAuthId);
        if (!smsFlag) {
            rglog.error("短信验证码校验失败！");
            throw new BizException(OltpRpcdEnum.VERIFY_SMS_CODE_ERROR.getRespCode(), OltpRpcdEnum.VERIFY_SMS_CODE_ERROR.getRespDesc());
        }
        rglog.info("查询绑定用户信息");
        /*根据用户标识查询用户信息*/
        BspsUserInfoMapper bspsUserInfoMapper = new BspsUserInfoMapperImpl();
        UserInfo userInfo = bspsUserInfoMapper.selectBspsUserInfoByUserId(instId, bindUserId);
        if (null == userInfo) {
            rglog.error("用户信息查询失败!");
            throw new BizException(RespCodeEnum.GET_USER_INFO_ERROR.getRespCode(), RespCodeEnum.GET_USER_INFO_ERROR.getRespDesc());
        }
        rglog.info("查询用户绑定商户信息");
        //查询绑定用户商户绑定关系表信息
        BspsMchntBindInfoMapper bspsMchntBindInfoMapper = new BspsMchntBindInfoMapperImpl();
        MchntBindInfo mchntBindInfo = bspsMchntBindInfoMapper.selectBspsMchntBindInfoListByUserIdAndMchntNo(instId, bindUserId, mchntNo);
        if (null == mchntBindInfo) {
            rglog.error("用户绑定商户状态异常!");
            throw new BizException(RespCodeEnum.GET_USER_BIND_INFO_ERROR.getRespCode(), RespCodeEnum.GET_USER_BIND_INFO_ERROR.getRespDesc());
        }
        //根据商户号查询商户基本信息
        BspsMchntBaseInfoMapper bspsMchntBaseInfoMapper = new BspsMchntBaseInfoMapperImpl();
        MchntBaseInfo mchntBaseInfo = bspsMchntBaseInfoMapper.selectBspsMchntBaseInfoByPrimaryKey(instId, mchntBindInfo.getMchntNo());
        if (null == mchntBaseInfo) {
            rglog.error("查询用户基本信息失败!");
            throw new BizException(RespCodeEnum.QUERY_MCHNT_BASE_INFO_ERROR.getRespCode(), RespCodeEnum.QUERY_MCHNT_BASE_INFO_ERROR.getRespDesc());
        }
        //判断商户状态
        if (!MchntStatusEnum.NORMAL.getStatus().equals(mchntBaseInfo.getMchntStatus())) {
            rglog.error("商户状态异常!");
            throw new BizException(RespCodeEnum.MCHNT_STATUS_ABNORMAL.getRespCode(), RespCodeEnum.MCHNT_STATUS_ABNORMAL.getRespDesc());
        }

        /*更新用户信息*/
        if (!StringUtil.isEmptyOrNull(userMobileId)) {
            /*手机账户赋值*/
            userInfo.setUserMobileId(userMobileId);
            /*最后操作时间赋值*/
            userInfo.setLastUpdateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
            /*最后操作人赋值*/
            userInfo.setLastOprId(userInfo.getUserId());
        }
        /*新增用户登录信息*/
        UserLoginInfo userLoginInfo = new UserLoginInfo();
        /*法人行赋值*/
        userLoginInfo.setInstId(instId);
        /*登录方式赋值*/
        userLoginInfo.setLoginType(BspsLoginTypeEnum.OPEN_ID.getLoginType());
        /*用户标识赋值*/
        userLoginInfo.setUserId(userInfo.getUserId());
        /*登录时间赋值*/
        userLoginInfo.setLoginTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        /*最后操作时间赋值*/
        userLoginInfo.setLastOprTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        /*登录状态赋值*/
        userLoginInfo.setLoginStatus("0");
        userLoginInfo.setSessionId(mobileBankMchntNoBindMchntRequest.getHeader().getSession());
        /*新增设备绑定信息*/
        DevBindInfo devBindInfo = new DevBindInfo();
        /*法人行赋值*/
        devBindInfo.setInstId(instId);
        /*设备类型赋值*/
        devBindInfo.setBindDevType(BindDevEnum.PHONE_DEV.getDevCode());
        /*设备唯一标识赋值*/
        devBindInfo.setBindDevId(devUniqueId);
        /*绑定用户信息赋值*/
        devBindInfo.setBindUserId(bindUserId);
        /*商户号赋值*/
        devBindInfo.setBindMchntNo(mchntNo);
        /*商户类型赋值*/
        devBindInfo.setBindMchntType(mchntBaseInfo.getMchntType());
        /*连锁商户号赋值*/
        devBindInfo.setChainMchntNo(mchntBaseInfo.getChainMchntNo());
        /*设备品牌赋值：需前端上送相关参数信息*/
        /*设备型号赋值*/
        if (!StringUtil.isEmptyOrNull(devModel)) {
            devBindInfo.setBindDevModel(devModel);
        }
        /*默认绑定状态赋值*/
        devBindInfo.setBindStatus(BindStatusEnum.BIND.getStatus());
        /*绑定日期赋值*/
        devBindInfo.setBindDate(DateUtil.getCurrentDate());
        /*绑定时间赋值*/
        devBindInfo.setBindTime(DateUtil.getCurrentTime());
        /*消息推送开关赋值*/
        devBindInfo.setMsgPushFlag(MsgPushEnum.ON.getMsgPushCode());
        /*消息推送key赋值:设备唯一标识*/
        devBindInfo.setMsgPushKey(devUniqueId);
        /*记录状态默认赋值*/
        devBindInfo.setRecordStatus("Y");
        /*审核状态默认赋值*/
        devBindInfo.setAuditStatus(AuditStatusEnum.ADD_AUDIT_SUCCESS.getAuditStatus());
        /*创建人赋值*/
        devBindInfo.setOprId(userInfo.getUserId());
        /*创建时间赋值*/
        devBindInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        devBindInfo.setMsgPushFlag("Y");
        devBindInfo.setBindDevModel(phoneBrandModel);
        /*执行数据库事物操作*/
        mobileMchntNoBindMchnt(userInfo, userLoginInfo, devBindInfo);

        /*查询用户权限信息*/
        /*根据用户绑定商户角色查询权限*/
        BspsUserRoleInfoMapper bspsUserRoleInfoMapper = new BspsUserRoleInfoMapperImpl();
        List<UserRoleInfo> userRoleInfoList = bspsUserRoleInfoMapper.selectBspsUserRoleInfoToChannelMenu(instId, mchntBindInfo.getBindUserRole(), channelId);
        /*角色权限赋值*/
        List<PrivilegeInfoBean> privilegeInfoList = new ArrayList<>();
        if (null != userRoleInfoList && !userRoleInfoList.isEmpty()) {
            userRoleInfoList.forEach(item -> convUserRoleInfo(item, privilegeInfoList));
        }
        /*将用户信息放入redis缓存中*/
        UserSessionInfo keySessionInfo = JSON.parseObject(RedisUtil.onceGet(header.getSession()), UserSessionInfo.class);
        keySessionInfo.setUserId(userInfo.getUserId());
        RedisUtil.onceSet(header.getSession(), JSONObject.toJSONString(keySessionInfo), BspsAppParamConstant.SESSION_EFFECTIVE_TIME);

        String newSessionId = RandomUtil.getUUID();
        UserSessionInfo userSessionInfo = new UserSessionInfo();
        userSessionInfo.setUserId(userInfo.getUserId());
        userSessionInfo.setSignatureKey(keySessionInfo.getSignatureKey());
        userSessionInfo.setSensitiveKey(keySessionInfo.getSensitiveKey());
        RedisUtil.onceSet(newSessionId, JSONObject.toJSONString(userSessionInfo), BspsAppParamConstant.SESSION_EFFECTIVE_TIME);
        header.setSession(newSessionId);

        /*组装返回报文*/
        MchntBindInfoBean mchntBindInfoBean = new MchntBindInfoBean();
        /*商户名赋值*/
        mchntBindInfoBean.setMchntName(mchntBaseInfo.getMchntName());
        /*商户号赋值*/
        mchntBindInfoBean.setMchntNo(mchntBaseInfo.getMchntNo());
        /*连锁商户号赋值*/
        mchntBindInfoBean.setChainMchntNo(mchntBaseInfo.getChainMchntNo());
        /*绑定状态赋值*/
        mchntBindInfoBean.setBindStatus(mchntBindInfo.getBindStatus());
        /*绑定时间赋值*/
        mchntBindInfoBean.setBindTime(mchntBindInfo.getBindDate() + " " + mchntBindInfo.getBindTime());
        /*绑定角色赋值*/
        mchntBindInfoBean.setBindUserRole(mchntBindInfo.getBindUserRole());
        /*用户角色权限赋值*/
        mchntBindInfoBean.setPrivilegeInfoBeanList(privilegeInfoList);
        List<MchntBindInfoBean> mchntBindInfoList = new ArrayList<>();
        mchntBindInfoList.add(mchntBindInfoBean);

        MobileBankMchntNoBindMchntResponse mobileBankMchntNoBindMchntResponse = new MobileBankMchntNoBindMchntResponse();
        mobileBankMchntNoBindMchntResponse.setHeader(header);
        /*昵称赋值*/
        mobileBankMchntNoBindMchntResponse.setNickName(userInfo.getNickName());
        /*性别赋值*/
        mobileBankMchntNoBindMchntResponse.setUserSex(userInfo.getUserSex());
        /*邮箱赋值*/
        mobileBankMchntNoBindMchntResponse.setEmail(userInfo.getEmail());
        //userId赋值
        mobileBankMchntNoBindMchntResponse.setUserId(userInfo.getUserId());
        /*头像赋值*/
        if (!StringUtil.isEmptyOrNull(userInfo.getUserImagePath())) {
            mobileBankMchntNoBindMchntResponse.setUserImagePath(Base64.encodeBase64String(userInfo.getUserImagePath().getBytes()));
        }
        mobileBankMchntNoBindMchntResponse.setMsgPushFlag(devBindInfo.getMsgPushFlag());
        /*商户绑定关系赋值*/
        mobileBankMchntNoBindMchntResponse.setMchntBindInfoBeanList(mchntBindInfoList);
        /* 按照接口转换基础产品信息并响应给请求方 */
        BizResponse<MobileBankMchntNoBindMchntResponse> bizResponse = new BizResponse<>();
        bizResponse.setRspSysId(AppParamConstant.SYS_ID);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(mobileBankMchntNoBindMchntResponse);
        return bizResponse;
    }

    /**
     * 手机银行通过商户号认证绑定商户
     * userInfo  用户信息
     * userLoginInfo 用户登录信息
     * devBindInfo 设备绑定信息
     */
    private void mobileMchntNoBindMchnt(UserInfo userInfo, UserLoginInfo userLoginInfo, DevBindInfo devBindInfo) throws Exception {
        /*新增设备绑定信息*/
        BspsDevBindInfoMapper bspsDevBindInfoMapper = new BspsDevBindInfoMapperImpl();
        /*查询设备是否有绑定*/
        DevBindInfo devExsitBindInfo = bspsDevBindInfoMapper.selectBspsDevBindInfoByDevUniqueIdAndDevType(devBindInfo.getInstId(), devBindInfo.getBindDevId(), devBindInfo.getBindDevType(), null);
        /* 开启数据库事务 */
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(AppConfigConstant.DATABASE_CONF_NODE, AppConfigConstant.OLTP_POOL_NAME);
        String corporation = xmlTreeUtil.getXmlTreeStringValue(AppParamConstant.CORPORATION);
        if (null != corporation && !corporation.isEmpty()) {
            String dbPoolCashNode = corporation.trim() + AppParamConstant.DATABASE_CONF_NODE;
            dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(dbPoolCashNode, AppConfigConstant.OLTP_POOL_NAME);
        }
        DbsUtil dbsUtil = new DbsUtil(dbPoolName);
        dbsUtil.dbsBeginTransaction();
        int iReturnCode;
        if (!UserDefaultEnum.MOBILEID.getDefaultId().equals(userInfo.getUserMobileId())) {
            /*更新用户信息*/
            BspsUserInfoMapper bspsUserInfoMapper = new BspsUserInfoMapperImpl();
            iReturnCode = bspsUserInfoMapper.updateBspsUserInfoByPrimaryKey(userInfo);
            if (0 != iReturnCode) {
                dbsUtil.dbsEndTransaction(false);
                rglog.error("更新用户信息失败！");
                throw new BizException(RespCodeEnum.UPDATE_USER_INFO_ERROR.getRespCode(), RespCodeEnum.UPDATE_USER_INFO_ERROR.getRespDesc());
            }
        }
        /*新增用户登录信息*/
        BspsUserLoginInfoMapper bspsUserLoginInfoMapper = new BspsUserLoginInfoMapperImpl();
        iReturnCode = bspsUserLoginInfoMapper.insertBspsUserLoginInfo(userLoginInfo);
        if (0 != iReturnCode) {
            dbsUtil.dbsEndTransaction(false);
            rglog.error("用户登录信息新增失败！");
            throw new BizException(RespCodeEnum.REGISTER_USER_LOGIN_INFO_ERROR.getRespCode(), RespCodeEnum.REGISTER_USER_LOGIN_INFO_ERROR.getRespDesc());
        }
        if (devExsitBindInfo == null) { //没有进行添加
            iReturnCode = bspsDevBindInfoMapper.insertBspsDevBindInfo(devBindInfo);
            if (0 != iReturnCode) {
                dbsUtil.dbsEndTransaction(false);
                rglog.error("新增设备绑定信息数据失败！");
                throw new BizException(RespCodeEnum.INSERT_DEVBIND_ERROR.getRespCode(), RespCodeEnum.INSERT_DEVBIND_ERROR.getRespDesc());
            }
        } else {//设备有绑定过 进行更新
            iReturnCode = bspsDevBindInfoMapper.updateBspsDevBindInfoByPrimaryKey(devBindInfo);
            if (0 != iReturnCode) {
                dbsUtil.dbsEndTransaction(false);
                rglog.error("更新设备绑定信息数据失败！");
                throw new BizException(RespCodeEnum.INSERT_DEVBIND_ERROR.getRespCode(), RespCodeEnum.INSERT_DEVBIND_ERROR.getRespDesc());
            }
        }
        dbsUtil.dbsEndTransaction(true);

    }

    /**
     * 用户权限信息装换、
     * userRoleInfo 用户权限信息
     **/
    private void convUserRoleInfo(UserRoleInfo userRoleInfo, List<PrivilegeInfoBean> privilegeInfoList) {
        PrivilegeInfoBean privilegeInfo = new PrivilegeInfoBean();
        /*菜单标识赋值*/
        privilegeInfo.setMenuId(userRoleInfo.getMenuId());
        /*菜单名称赋值*/
        privilegeInfo.setMenuName(userRoleInfo.getMenuName());
        /*功能权限标识*/
        privilegeInfo.setFuncDroitId(userRoleInfo.getFuncDroitId());
        /*功能权限名称赋值*/
        privilegeInfo.setFuncDroitDesc(userRoleInfo.getFuncDroitDesc());
        /*菜单页面路径赋值*/
        privilegeInfo.setMenuUrlPath(userRoleInfo.getMenuUrlPath());
        /* 上级菜单 */
        privilegeInfo.setSuperMenuId(userRoleInfo.getSuperMenuId());
        /* 菜单是否隐藏标识 */
        privilegeInfo.setMenuHideFlag(userRoleInfo.getMenuHideFlag());
        BeanUtil.beanCopy(userRoleInfo, privilegeInfo);
        privilegeInfoList.add(privilegeInfo);
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        MobileBankMchntNoBindMchntResponse mobileBankMchntNoBindMchntResponse = (MobileBankMchntNoBindMchntResponse) bizResponse.getResult();
        ConvertUtil.convertInput(mobileBankMchntNoBindMchntResponse);

    }
}